Passed
Push — master ( 8d43c8...457e33 )
by Night
01:12
created

numberFuncs.sqrt   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 1
eloc 3
c 1
b 1
f 1
nc 1
nop 0
dl 0
loc 4
rs 10
1
/** global: UB */
2
3
UB.intMaxValue = 2147483647;
4
UB.intMinValue = -2147483648;
5
UB.floatMaxValue = 3.40282e+038; /// 038 or 056? .. it was originally 038F
6
UB.floatMinValue = -3.40282e+038;
7
UB.doubleMaxValue =  9223372036854775807;
8
UB.doubleMinValue = -9223372036854775808;
9
10
UB.roman1s = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"];
11
UB.roman10s = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"];
12
UB.roman100s = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"];
13
UB.roman1000s = ["", "m", "mm", "mmm", "mmmm", "", "", "", "", ""];
14
UB.roman = [UB.roman1s, UB.roman10s, UB.roman100s, UB.roman1000s];
15
16
UB.letterLegal = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH", "II", "JJ", "KK", "LL", "MM", "NN", "OO", "PP", "QQ", "RR", "SS", "TT", "UU", "VV", "WW", "XX", "YY", "ZZ", "AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH", "III", "JJJ", "KKK", "LLL", "MMM", "NNN", "OOO", "PPP", "QQQ", "RRR", "SSS", "TTT", "UUU", "VVV", "WWW", "XXX", "YYY", "ZZZ", "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLL", "MMMM", "NNNN", "OOOO", "PPPP", "QQQQ", "RRRR", "SSSS", "TTTT", "UUUU", "VVVV", "WWWW", "XXXX", "YYYY", "ZZZZ", "AAAAA", "BBBBB", "CCCCC", "DDDDD", "EEEEE", "FFFFF", "GGGGG", "HHHHH", "IIIII", "JJJJJ", "KKKKK", "LLLLL", "MMMMM", "NNNNN", "OOOOO", "PPPPP", "QQQQQ", "RRRRR", "SSSSS", "TTTTT", "UUUUU", "VVVVV", "WWWWW", "XXXXX", "YYYYY", "ZZZZZ"];
17
UB.letterExcel = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ", "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ"];
18
19
UB.decZeros = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
20
UB.hexChars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
21
UB.toDegrees = (180 / Math.PI);
22
UB.toRadians = (Math.PI / 180);
23
24
UB.minOf3 = function(num1, num2, num3){
25
	if (num1 < num2) {
26
		if (num1 < num3) {
27
			return num1;
28
		}
29
		return num3;
30
	}
31
	if (num2 < num3) {
32
		return num2;
33
	}
34
	return num3;
35
};
36
UB.maxOf3 = function(num1, num2, num3){
37
	if (num1 > num2) {
38
		if (num1 > num3) {
39
			return num1;
40
		}
41
		return num3;
42
	}
43
	if (num2 > num3) {
44
		return num2;
45
	}
46
	return num3;
47
};
48
49
UB.minOf4 = function(num1, num2, num3, num4){
50
	if (num1 < num2) {
51
		
52
		// 1, 3, 4
53
		if (num1 < num3) {
54
			
55
			// 1, 4
56
			if (num1 < num4) {
57
				return num1;
58
			}
59
			return num4;
60
		}
61
		
62
		// 3, 4
63
		if (num3 < num4) {
64
			return num3;
65
		}
66
		return num4;
67
		
68
	}
69
	
70
	// 2, 3, 4
71
	if (num2 < num3) {
72
		
73
		// 2, 4
74
		if (num2 < num4) {
75
			return num2;
76
		}
77
		return num4;
78
	}
79
	
80
	// 3, 4
81
	if (num3 < num4) {
82
		return num3;
83
	}
84
	return num4;
85
};
86
UB.maxOf4 = function(num1, num2, num3, num4){
87
	if (num1 > num2) {
88
		
89
		// 1, 3, 4
90
		if (num1 > num3) {
91
			
92
			// 1, 4
93
			if (num1 > num4) {
94
				return num1;
95
			}
96
			return num4;
97
		}
98
		
99
		// 3, 4
100
		if (num3 > num4) {
101
			return num3;
102
		}
103
		return num4;
104
		
105
	}
106
	
107
	// 2, 3, 4
108
	if (num2 > num3) {
109
		
110
		// 2, 4
111
		if (num2 > num4) {
112
			return num2;
113
		}
114
		return num4;
115
		
116
	}
117
	
118
	// 3, 4
119
	if (num3 > num4) {
120
		return num3;
121
	}
122
	return num4;
123
};
124
125
/** calc overlap of 2 numeric ranges */
126
UB.overlap = function(value1Start, value1End, value2Start, value2End){
127
	
128
	// swap if reversed
129
	if (value1Start > value1End) {
130
		var temp = value1Start;
131
		value1Start = value1End;
132
		value1End = temp;
133
	}
134
	if (value2Start > value2End) {
135
		temp = value2Start;
136
		value2Start = value2End;
137
		value2End = temp;
138
	}
139
	
140
	// exit if no overlap
141
	if (value1End < value2Start || value2End < value1Start) {
142
		return 0;
143
	}
144
	
145
	// return overlap of 2 ranges
146
	if (value1Start >= value2Start && value1End <= value2End) {
147
		return (value1End - value1Start);
148
	} else if (value2Start >= value1Start && value2End <= value1End) {
149
		return (value2End - value2Start);
150
	} else if (value1Start < value2Start && value1End <= value2End) {
151
		return (value1End - value2Start);
152
	} else if (value2Start < value1Start && value2End <= value1End) {
153
		return (value2End - value1Start);
154
	}
155
	return 0;
156
};
157
158
// distance between 2 lat/lon coords
159
UB.latLonDistance = function(latitude1, longitude1, latitude2, longitude2){
160
	
161
	// all lat/lons are floating point numbers in degrees
162
	
163
	var theta = longitude1 - longitude2;
164
	var miles = (Math.sin(latitude1*UB.toRadians)*Math.sin(latitude2*UB.toRadians)) + (Math.cos(latitude1*UB.toRadians)*Math.cos(latitude2*UB.toRadians)*Math.cos(theta*UB.toRadians));
165
	miles = Math.acos(miles);
166
	miles = (miles * UB.toDegrees);
167
	
168
	miles = miles * 60 * 1.1515;
169
	var feet = miles*5280;
170
	var yards = feet / 3;
171
	var kilometers = miles*1.609344;
172
	var meters = kilometers*1000;
173
	return [miles, feet, yards, kilometers, meters];
174
};
175
	
176
177
var stringFuncs = {
178
	
179
	/** CONVERT LEGAL LETTER TO NUMBER .. A = 1, B = 2, C = 3  */
180
	legalNumeralToNumber: function(zeroBased){
181
		var s = this.toString();
182
		return UB.letterLegal.indexOf(s.toUpperCase()) + (zeroBased ? 0 : 1);
183
	},
184
	/** CONVERT EXCEL COLUMN ID TO NUMBER .. A = 1, B = 2, C = 3  */
185
	excelColumnToNumber: function(zeroBased = false){
186
		var s = this.toString();
187
		return UB.letterExcel.indexOf(s.toUpperCase()) + (zeroBased ? 0 : 1);
188
	},
189
	
190
	hexToDecimal: function(onlyDigits = 0){
191
		var hex = this.toString();
192
		hex = hex.toUpperCase();
193
		
194
		// remove prefix
195
		if (hex.indexOf("0X") === 0){
196
			hex = hex.substr(2);
197
		}else if (hex.charAt(0) == "#"){
198
			hex = hex.substr(1);
199
		}
200
		
201
		if (onlyDigits) {
202
			hex = hex.substr(0, onlyDigits);
203
		}
204
		return int("0x" + hex);
205
	},
206
	
207
	binaryToDecimal: function(){
208
		var bin = this.toString();
209
		var num = bin.toString();
0 ignored issues
show
Unused Code introduced by
The variable num seems to be never used. Consider removing it.
Loading history...
210
		bin = bin.toUpperCase();
211
		
212
		// remove prefix
213
		if (bin.indexOf("0B") === 0){
214
			bin = bin.substr(2);
215
		}
216
		
217
		var byte = 0;
218
		for (var i = 0, il = bin.length, il2 = bin.length - 1;i<il;i++){
219
			byte += uint(bin.charAt(il2 - i)) * Math.pow(2,i);
220
		}
221
		return byte;
222
	},
223
	
224
	none:null
225
};
226
227
// register funcs
228
UB.registerFuncs(String.prototype, stringFuncs);
229
230
231
232
var numberFuncs = {
233
	
234
	isOdd: function(){
235
		var val = this;
236
		return (val % 2) != 0;
237
	},
238
	isEven: function(){
239
		var val = this;
240
		return (val % 2) === 0;
241
	},
242
	isPositive: function(){
243
		var val = this;
244
		return (val > 0);
245
	},
246
	isNegative: function(){
247
		var val = this;
248
		return (val < 0);
249
	},
250 View Code Duplication
	relativeTo: function(v2, type){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
		var v1 = this;
252
		// type .. 0=any, 1=pos, 2=neg
253
		var v = v2 - v1;
254
		if (type == 1) {
255
			return v > 0 ? v : -v;
256
		}else if (type == 2) {
257
			return v > 0 ? -v : v;
258
		}
259
		return v;
260
	},
261
	round: function(){
262
		return Math.round(this);
263
	},
264
	ceil: function(){
265
		return Math.ceil(this);
266
	},
267
	floor: function(){
268
		return Math.floor(this);
269
	},
270
	abs: function(negative = false){
271
		var v = this;
272
		if (negative){
273
			return v > 0 ? -v : v;
274
		}
275
		return v > 0 ? v : -v;
276
	},
277
	acos: function(degrees = false){
278
		var v = this;
279
		if (degrees) {
280
			return Math.acos(v) * UB.toDegrees;
281
		}
282
		return Math.acos(v);
283
	},
284
	asin: function(degrees = false){
285
		var v = this;
286
		if (degrees) {
287
			return Math.asin(v) * UB.toDegrees;
288
		}
289
		return Math.asin(v);
290
	},
291
	atan: function(degrees = false){
292
		var v = this;
293
		if (degrees) {
294
			return Math.atan(v) * UB.toDegrees;
295
		}
296
		return Math.atan(v);
297
	},
298
	atan2: function(x, degrees = false){
299
		var y = this;
300
		if (degrees) {
301
			return Math.atan2(y, x) * UB.toDegrees;
302
		}
303
		return Math.atan2(y, x);
304
	},
305
	exp: function(){
306
		var v = this;
307
		return Math.exp(v);
308
	},
309
	log: function(){
310
		var v = this;
311
		return Math.log(v);
312
	},
313
	pow: function(power){
314
		var base = this;
315
		return Math.pow(base, power)
316
	},
317
	sin: function(degrees = false){
318
		var angle = this;
319
		if (degrees) {
320
			return Math.sin(angle * UB.toRadians);
321
		}
322
		return Math.sin(angle);
323
	},
324
	cos: function(degrees = false){
325
		var angle = this;
326
		if (degrees) {
327
			return Math.cos(angle * UB.toRadians);
328
		}
329
		return Math.cos(angle);
330
	},
331
	tan: function(degrees = false){
332
		var angle = this;
333
		if (degrees) {
334
			return Math.tan(angle * UB.toRadians);
335
		}
336
		return Math.tan(angle);
337
	},
338
	sqrt: function(){
339
		var v = this;
340
		return Math.sqrt(v);
341
	},
342
	compare: function(v2){
343
		var v1 = this;
344
		if (v1 < v2) {
345
			return -1;
346
		}
347
		if (v1 > v2) {
348
			return 1;
349
		}
350
		return 0;
351
	},
352
	positive: function(){
353
		var val = this;
354
		return val > 0 ? val : -val;
355
	},
356
	negative: function(){
357
		var val = this;
358
		return val > 0 ? -val : val;
359
	},
360
	
361
	exists: function(zeroOK = false){
362
		var v = this;
363
		if (zeroOK) {
364
			return (v != null && v == v);
365
		}
366
		return v != null && v == v && v != 0;
367
	},
368
	
369
	
370
	min: function(num2){
371
		var num1 = this;
372
		if (num1 < num2) {
373
			return num1;
374
		}
375
		return num2;
376
	},
377
	max: function(num2){
378
		var num1 = this;
379
		if (num1 > num2) {
380
			return num1;
381
		}
382
		return num2;
383
	},
384
	atMost: function(limit){
385
		var num = this;
386
		return num > limit ? limit : num;
387
	},
388
	atLeast: function(limit){
389
		var num = this;
390
		return num < limit ? limit : num;
391
	},
392
	
393
	
394
	isNear: function(target, near = 1){
395
		var val = this;
396
		return val >= (target - near) && val <= (target + near);
397
	},
398
	
399
400
	/** Render a percentage (25%) using 2 values */
401
	percentageToString: function(current, decimals = 0){
402
		var total = this;
403
		return ((current / total) * 100).roundTo(decimals) + "%";
404
	},
405
	
406
407
	// CONVERT TO ABBREVIATION .. 1.5K
408
	toAbbreviation: function(decimals = 1){
409
		var num = this;
410
		if (num < 0) {
411
			return "-" + (-num).toAbbreviation; // -5.2K, -5.2M ..
412
		}
413
		if (num < 1000) {
414
			return String(num); // 520
415
		}
416
		if (num < 1000000) {
417
			return (num / 1000).roundToDigits(decimals) + 'K'; // 5.2K
418
		}
419
		if (num < 1000000000) {
420
			return (num / 1000000).roundToDigits(decimals) + 'M'; // 5.2M
421
		}
422
		return (num / 1000000000).roundToDigits(decimals) + 'G'; // 5.2B
423
	},
424
	
425
	
426
	// CONVERT TO ROMAN
427
	toRomanNumeral: function(){
428
		var n = this;
429
		if (n < 1) {
430
			n = 1;
431
		}
432
		
433
		// exit quickly if single digit
434
		if (n <= 9) {
435
			return UB.roman1s[n];
436
		}
437
		
438
		// create roman number if longer
439
		var str = n.toString();
440
		var output = [];
441
		for (var n = 0, nl = str.length;n<nl;n++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable n already seems to be declared on line 428. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
442
			var series = ((nl - 1) - n);
443
			var charIndex = int(str.charAt(n));
444
			output.push(UB.roman[series][charIndex]);
445
		}
446
		return output.join("");
447
	},
448
	
449
	/** CONVERT TO LEGAL LETTER .. 1 = A, 2 = B, 3 = C .. AA, BB, CC */
450
	toLegalNumeral: function(){
451
		var n = this;
452
		if (n < 1) {
453
			n = 1;
454
		}
455
		return UB.letterLegal[n];
456
	},
457
	// CONVERT TO NORMAL LETTER .. A, B, C .. AB, AB, AC .. BA, BB, BC
458
	toLetterNumeral: function(){
459
		var n = this;
460
		if (n <= 26) {
461
			return UB.letterLegal[n];
462
		}
463
		return "?";
464
	},
465
	/** CONVERT TO EXCEL COLUMN ID .. 1 = A, 2 = B, 3 = C .. AA, AB, AC */
466
	toExcelColumn: function(zeroBased = false){
467
		var n = this;
468
		var min = zeroBased?0:1;
469
		if (n < min) {
470
			n = min;
471
		}
472
		return UB.letterExcel[zeroBased ? n : n-1];
473
	},
474
	
475
	// CONVERT TO ORDINAL FORMAT .. 1st, 2nd, 3rd
476
	toOrdinal: function(){
477
		var i = this;
478
		var j = i % 10;
479
		var k = i % 100;
480
		if (j == 1 && k != 11) {
481
			return i + "st";
482
		}
483
		if (j == 2 && k != 12) {
484
			return i + "nd";
485
		}
486
		if (j == 3 && k != 13) {
487
			return i + "rd";
488
		}
489
		return i + "th";
490
	},
491
	
492
	
493
	// OR
494
	or: function(returnVal, ifNull = 0){
495
		var n = this;
496
		if (n == ifNull) {
497
			return returnVal;
498
		}
499
		return n;
500
	},
501
	
502
	
503
	/** Calc padding for a given length */
504
	padding: function(multipleOf){
505
		var length = this;
506
		return (multipleOf - (length % multipleOf));
507
	},
508
	
509
	multipleOf: function(multipleOf){
510
		var value = this;
511
		return value + (multipleOf - (value % multipleOf));
512
	},
513
	
514
	
515
	// FROM C#
516
	
517
	distance: function(n2){
518
		var n1 = this;
519
		return Math.abs(n1 - n2);
520
	},
521
	
522
	/** Calc x % of the given value */
523
	percentage: function(percentWanted){
524
		var val100Percent = this;
525
		if (percentWanted == 100) {
526
			return val100Percent;
527
		}
528
		return val100Percent * (percentWanted / 100.0);
529
	},
530
	
531
	/** Calc the % of otherVal in relation to val100Percent */
532
	percentOf: function(otherVal){
533
		var val100Percent = this;
534
		return (otherVal / val100Percent) * 100.0;
535
	},
536
	
537
	/** Calc the difference between 2 numbers in %
538
	//  ... 100, 50 shows -50% difference
539
	//  ... 100, 150 shows 50% difference */
540
	percentDifference: function(otherVal){
541
		var val100Percent = this;
542
		return ((otherVal - val100Percent) / val100Percent) * 100.0;
543
	},
544
	
545
	isConsequetive: function(value, value2){
546
		return value2 == (value - 1) || value2 == (value + 1);
547
	},
548
	
549
	/** Returns the number halfway between the 2 given numbers
550
		Value1 can be greater than Value2. */
551
	between: function(value2){
552
		return this.middle(value2);
553
	},
554
	
555
	/** Returns the number halfway between the 2 given numbers
556
		Value1 can be greater than Value2. */
557
	middle: function(value2){
558
		var value1 = this;
559
		if (value1 > value2) {
560
			return value2 + ((value1 - value2) / 2);
561
		}
562
		return value1 + ((value2 - value1) / 2);
563
	},
564
	
565
	calcScale: function(targetValue){
566
		var value = this;
567
		if (targetValue === 0 && value === 0) {
568
			return 0;
569
		}
570
		return (value / targetValue);
571
	},
572
	
573
	ensure: function(defaultVal){
574
		var value = this;
575
		if (value === 0) {
576
			return defaultVal;
577
		}
578
		return value;
579
	},
580
	
581
	snapToHigher: function(snapBy){
582
		var val = this;
583
		return Math.ceil(val / snapBy) * snapBy;
584
	},
585
	snapToLower: function(snapBy){
586
		var val = this;
587
		return Math.floor(val / snapBy) * snapBy;
588
	},
589
	snapToNearest: function(snapBy){
590
		var val = this;
591
		return Math.round(val / snapBy) * snapBy;
592
	},
593
	
594
	toInt: function(round){
595
		var num = this;
596
		if (!round || round == "truncate") {
597
			return parseInt(num);
598
		}
599
		if (round == "round") {
600
			return Math.round(num);
601
		}
602
		if (round == "floor") {
603
			return Math.floor(num);
604
		}
605
		if (round == "ceiling") {
606
			return Math.ceil(num);
607
		}
608
		return 0;
609
	},
610
	
611
	/**
612
	 * Formats a Number adding commas and the specified decimal digits.
613
	 * Supports the million/billion and lakh/crore system.
614
	 * 
615
	 * @param	system					"million" or "lakh"
616
	 * @param	decimals				-1 = keep exact decimals as number, 0 = no decimals, 1+ = specific decimals
617
	 * @param	alwaysShowDecimal		add decimal even if decimal part is 0
618
	 */
619
	formatNumber: function(system, decimals = -1, alwaysShowDecimal = false){
620
		var num = this;
621
		
622
		var commas = system == "lakh" ? 2 : 3;
623
624
		// test if number is negative
625
		var neg = false;
626
		if (num < 0) {
627
			neg = true;
628
			num = -num;
629
		}
630
		// get the left number
631
		var numStr = String(num);
632
		var hasDot = numStr.indexOf(".")>-1;
633
		if (hasDot) {
634
			var parts = numStr.split(".");
635
			var whole = parts[0];
636
			var decimal = parts[1];
637
		}else{
638
			whole = numStr;
639
			decimal = null;
640
		}
641
		
642
		// if at least 4 digits
643
		if (whole.length > 3) {
644
			
645
			// extract 3 digits first 
646
			var wholeRight3 = whole.substr(whole.length - 3, 3);
647
			whole = whole.substr(0, whole.length - 3);			
648
			
649
			// add million / crore seperators
650
			if (whole.length < commas) {
651
				whole = whole + "," + wholeRight3;
652
			}else {
653
				var thou = "";
654
				var rem = whole.substr(0, int(whole.length % commas));
655
				var l = ((int(whole.length / commas)*commas) - commas) + (whole.length % commas);
656
				for (var c = 0;l >= 0;l -= commas, c++){
0 ignored issues
show
Unused Code introduced by
The loop variable c is initialized by the loop but not used in the test. Consider using another type of loop if this is the intended behavior.
Loading history...
657
					thou = whole.substr(l, commas) + (c === 0 ? "" : ",") + thou;
658
				}
659
				whole = (rem == "" ? "" : rem + ",") + thou + "," + wholeRight3;
660
			}
661
		}
662
		
663
		// return with or without dot
664
		var result = whole;
665
		if (hasDot) {
666
			if (decimals > 0) {
667
				//  4.200
668
				result = whole + "." + decimal.substr(0, decimals).padRight("0", decimals);
669
			}else if (decimals === 0) {
670
				//  4
671
				result = whole;
672
			}else if (decimals === -1) {
673
				//  4.2
674
				result = whole + "." + decimal;
675
			}
676
			
677
		}else if (alwaysShowDecimal && decimals > 0) {
678
			
679
			//  4.0000
680
			result = whole + "." + decimals.repeat("0");
681
		}else {
682
			
683
			//  4
684
			result = whole;
685
		}
686
		return (neg ? "-" + result : result);
687
	},
688
	
689
	ensureNotNaN: function(instead = 0){
690
		var val = this;
691
		if (val != val) { /// fast isNaN check
692
			return instead;
693
		}
694
		return val;
695
	},
696
	
697
	isNaN: function(){
698
		var val = this;
699
		return val != val || isNaN(val);
700
	},
701
	
702
	isAny: function(haystacks, asInt = false, fractionalDigits = -1){
703
		var needle = this;
704
		
705
		// return true if any haystack equals the needle
706
		for (var s = 0, sl = haystacks.length;s<sl;s++){
707
			var num = haystacks[s];
708
			
709
			// simplify value for comparison
710
			if (asInt) {
711
				num = int(num);
712
			}else if(fractionalDigits != -1) {
713
				num = num.roundToDigits(fractionalDigits);
714
			}
715
			
716
			if (needle == num) {
717
				return true;
718
			}
719
		}
720
		return false;
721
	},
722
	
723
	scale: function(inputMin, inputMax, outputMin, outputMax, outputLimit = true, outputFlip = false){
724
		var input = this;
725
		
726
		// ensure input within limits
727
		if (input < inputMin) {
728
			input = inputMin;
729
		}
730
		if (input > inputMax) {
731
			input = inputMax;
732
		}
733
		
734
		// convert input to %
735
		var percent = ((1*(input - inputMin)) / (inputMax - inputMin));
736
		
737
		// convert % to output
738
		var output = (percent*(outputMax - outputMin)) + outputMin;
739
		
740
		// ensure output within limits
741
		if (outputLimit){
742
			if (output < outputMin) {
743
				output = outputMin;
744
			}
745
			if (output > outputMax) {
746
				output = outputMax;
747
			}
748
		}
749
		
750
		// flip output
751
		if (outputFlip) {
752
			output = ((outputMax - outputMin) - (output - outputMin)) + outputMin;
753
		}
754
		
755
		// return scaled, limit-checked output
756
		return output;
757
	},
758
	smartScale: function(inputMin, inputMax, outputMin, outputMax){
759
		var input = this;
760
		if (inputMin > inputMax) {
761
			if (outputMin > outputMax) {
762
				return input.flipWithin(inputMin, inputMax).scale(inputMax, inputMin, outputMax, outputMin, true, true);
763
			}
764
			return input.flipWithin(inputMin, inputMax).scale(inputMax, inputMin, outputMin, outputMax);
765
		}
766
		if (outputMin > outputMax) {
767
			return input.scale(inputMin, inputMax, outputMax, outputMin, true, true);
768
		}
769
		return input.scale(inputMin, inputMax, outputMin, outputMax);
770
	},
771
	
772
	flipWithin: function(min, max){
773
		var input = this;
774
		if (max < min) {
775
			return ((min - max) - (input - max)) + min;
776
		}
777
		return ((max - min) - (input - min)) + min;
778
	},
779
	
780
	limitToDigits: function(digits){
781
		var input = this;
782
		return parseFloat(input.toString().substr(0, digits));
783
	},
784 View Code Duplication
	limit: function(min, max){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
785
		var input = this;
786
		
787
		// ensure ok
788
		if (input != input) { /// fast isNaN check
789
			return min;
790
		}
791
		
792
		// flip limits if in reverse order
793
		if (min > max) {
794
			var temp = max;
795
			max = min;
796
			min = temp;
797
		}
798
		
799
		// ensure within limits
800
		if (input < min) {
801
			return min;
802
		}else if (input > max) {
803
			return max;
804
		}
805
		return input;
806
	},
807
	limitToArray: function(array, extraMax = 0, extraMin = 0){
808
		var pointer = this;
809
		if (pointer <= -extraMin) {
810
			return -extraMin;
811
		}
812
		var last = (array.length + extraMax) - 1;
813
		if (last === -1) {
814
			return -extraMin;
815
		}else if (pointer > last) {
816
			return last;
817
		}
818
		return pointer;
819
	},
820
	
821
	wrap: function(min, max){
822
		var value = this;
823
		value -= min;
824
		var diff = (max - min) + 1;
825
		while (value < 0) {
826
			value += diff;
827
		}
828
		return min + (value % diff);
829
	},
830 View Code Duplication
	wrap2: function(min, max){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
831
		var input = this;
832
		
833
		// flip limits if in reverse order
834
		if (min > max) {
835
			var temp = max;
836
			max = min;
837
			min = temp;
838
		}
839
		
840
		// ensure wrapped to limits
841
		var diff = (max - min) + 1;
842
		while (input < min) {
843
			input += diff;
844
		}
845
		while (input > max) {
846
			input -= diff;
847
		}
848
		return input;
849
	},
850
	wrapToMax: function(max){
851
		var value = this;
852
		var diff = max + 1;
853
		while (value < 0) {
854
			value += diff;
855
		}
856
		return value % diff;
857
	},
858
	
859
	/** Identical to modulo operator, except negative values are also supported, and brought into positive range.
860
		Value will never reach limit, just like the modulo operator.
861
		Simpler than `wrap` which takes `min` and `max`. */
862
	modulo: function(limit){
863
		var input = this;
864
		
865
		// ensure wrapped to limits
866
		while (input < 0) {
867
			input += limit;
868
		}
869
		while (input >= limit) {
870
			input -= limit;
871
		}
872
		return input;
873
	},
874
	
875
	roundToDigits: function(decimals = 4){
876
		var input = this;
877
		
878
		if (decimals <= 0) {
879
			return Math.round(input);
880
		}
881
		
882
		// Returns a number rounded to specified number of decimals
883
		var multiplier = Math.pow(10, decimals);
884
		return Math.round(input*multiplier)/multiplier;
885
	},
886
	roundTo: function(decimals){
887
		var input = this;
888
		
889
		// Returns a number rounded to specified number of decimals
890
		// Add zeros to always return those many decimals
891
		var num = input.roundToDigits(decimals).toString();
892
		if (decimals <= 0) {
893
			return num;
894
		}
895
		var add0 = 0;
896
		if (num.lastIndexOf(".") === -1){
897
			num = num+".";
898
			add0 = decimals;
899
		}else{
900
			add0 = decimals - ((num.length - num.lastIndexOf(".")) - 1);
901
		}
902
		while(add0 > 0){
903
			num = num+"0";
904
			add0 --;
905
		}
906
		return num;
907
	},
908
	
909
	
910
	// CHECKS
911
	/** Checks if the value is within min and max (supporting inclusive/exclusive modes) */
912
	isWithin: function(min, max, inclusive = true){
913
		var num = this;
914
		if (inclusive) {
915
			if (min > max) {
916
				return (num >= max && num <= min);
917
			}
918
			return (num >= min && num <= max);
919
		}
920
		
921
		if (min > max) {
922
			return (num > max && num < min);
923
		}
924
		return (num > min && num < max);
925
	},
926
	isWithinArray: function(arr){
927
		var slot = this;
928
		
929
		// no, if array empty / index negative / index more than last slot
930
		var len = arr.length;
931
		if (len === 0 || slot < 0 || slot >= len) {
932
			return false;
933
		}
934
		
935
		// else yes
936
		return true;
937
	},
938
	/** Checks if the value is > min and < max */
939
	isBetween: function(min, max){
940
		var num = this;
941
		return (num > min && num < max);
942
	},
943
	isOutside: function(min, max, inclusive = true){
944
		var num = this;
945
		if (inclusive) {
946
			return num <= min || num >= max;
947
		}
948
		return num < min || num > max;
949
	},
950
	isFractional: function(){
951
		var num = this;
952
		return int(num) != num;
953
	},
954
	isInteger: function(){
955
		var num = this;
956
		return int(num) == num;
957
	},
958
	
959
	
960
	// HEX
961
	toHex: function(digits = 6, withHash = true){
962
		var num = this;
963
		var zeros = ("0000000000000000000000000000000000").substr(0, digits - 1);
964
		return ((withHash ? "#" : "") + (zeros + num.toString(16).toUpperCase()).substr( -digits));
965
	},
966
	
967
	incrementWithin: function(min, max){
968
		var num = this;
969
		num++;
970
		if (num > max) {
971
			return min;
972
		}
973
		return num;
974
	},
975
	decrementWithin: function(min, max){
976
		var num = this;
977
		num--;
978
		if (num < min) {
979
			return max;
980
		}
981
		return num;
982
	},
983
	
984
	
985
	decimalToBinary: function(digits = 8){
986
		var num = this;
987
		var zeros = UB.decZeros.substr(0, digits - 1);
988
		return (zeros + num.toString(2)).substr( -digits);
989
	}, 
990
	decimalToBinary2: function(digits = 8){
991
		var byte = this;
992
		var bin = '';
993
		for (var i = 0;i<digits;i++){
994
			bin += String((byte & (0x80 >> i)) >> (7 - i));
995
		}
996
		return bin;
997
	},
998
	
999
	
1000
	
1001
	// MISC MATH
1002
	pad: function(length, addToEnd = false, padChar = '0'){
1003
		var number = this;
1004
		
1005
		// num to text
1006
		var result = String(number);
1007
		
1008
		// exit quickly if already reached target len
1009
		if (result.length >= length) {
1010
			return result;
1011
		}
1012
		
1013
		
1014
		// pad
1015
		if (addToEnd) {
1016
			while (result.length < length){
1017
				result = result + padChar;
1018
			}
1019
		}else {
1020
			while (result.length < length){
1021
				result = padChar + result;
1022
			}
1023
		}
1024
		
1025
		
1026
		return result;
1027
	},
1028
	interpolate: function(min, max){
1029
		var progress = this;
1030
		// progress = (0 to 1)
1031
		/*return( (1 - progress) * min + progress * max ); <---- WHAT IS THIS??? */ 
1032
		return min + ((max - min) * progress);
1033
	},
1034
	hypot: function(b){
1035
		var a = this;
1036
		// sqrt(a^2 + b^2) without under/overflow.
1037
		
1038
		var r;
1039
		var aAbs = (a > 0 ? a : -a);
1040
		var bAbs = (b > 0 ? b : -b);
1041
		if (aAbs > bAbs) {
1042
			r = b/a;
1043
			r = aAbs*Math.sqrt(1+r*r);
1044
		} else if (b != 0) {
1045
			r = a/b;
1046
			r = bAbs*Math.sqrt(1+r*r);
1047
		} else {
1048
			r = 0.0;
1049
		}
1050
		return r;
1051
	},
1052
	apow: function(value){
1053
		var pow = this;
1054
		// input:	1,2,4,8,16,32,64
1055
		// output:	1,2,3,4,5,6,7
1056
		if (value == 1 || value === -1) return value;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1057
		var count = 0;
1058
		while (value != 0) {
1059
			//remainder = value % pow;
1060
			value = value / pow;
1061
			count++;
1062
		}
1063
		return count;
1064
	},
1065
	invert: function(){
1066
		var value = this;
1067
		// input:	0.1		0.5		1 	2 		8
1068
		// output:	10		2		1	0.5		0.2
1069
		return 1 / value;
1070
	},
1071
	powAbs: function(exponent){
1072
		var x = this;
1073
		// This function always returns a positive value that conforms to the expected Exponent curve.
1074
		// Math.pow: If x is negative, and exponent is not an integer, returns NaN.
1075
		if( x >= 0 ) {
1076
			return Math.pow( x, exponent );
1077
		}
1078
		return Math.pow(-x, 1/exponent);
1079
	},
1080
	
1081
	// count digits in number
1082
	getWhole: function(){
1083
		var val = this;
1084
		
1085
		// -10.235 has 2 whole digits
1086
		return int(val);
1087
	},
1088
	setWhole: function(newval){
1089
		var val = this;
1090
		return newval + GetFractional(val);
1091
	},
1092
	getFractional: function(){
1093
		var val = this;
1094
		
1095
		// -10.235 has 3 fractional digits
1096
		var s = (val < 0 ? -val : val).toString();
1097
		var i = s.indexOf(".");
1098
		return (i === -1) ? int(val) : int(s.substr(i + 1));
1099
	},
1100
	setFractional: function(fraction){
1101
		var val = this;
1102
		return Number((parseInt(val).toString()) + "." + fraction.toString());
1103
	},
1104
	
1105
	
1106
	
1107
	// SLOT INDEX
1108
	minIndex: function(index2){
1109
		var index1 = this;
1110
		if (index1 <= -1) {
1111
			return index2;
1112
		}
1113
		if (index2 <= -1) {
1114
			return index1;
1115
		}
1116
		if (index1 < index2) {
1117
			return index1;
1118
		}
1119
		return index2;
1120
	},
1121
	maxIndex: function(index2){
1122
		var index1 = this;
1123
		if (index1 <= -1) {
1124
			return index2;
1125
		}
1126
		if (index2 <= -1) {
1127
			return index1;
1128
		}
1129
		if (index1 > index2) {
1130
			return index1;
1131
		}
1132
		return index2;
1133
	},
1134
	
1135
	
1136
	
1137
	none:null
1138
};
1139
1140
// register funcs
1141
UB.registerFuncs(Number.prototype, numberFuncs);
1142
1143